#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <memory>
#include <vector>
#include <thread>
#include <chrono>
#include <atomic>
#include <random>
#include <algorithm>

/**
 * 内存管理测试类
 * 测试WonderTrader组件的内存分配、释放和泄漏检测
 */
class MemoryManagementTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 记录测试开始时的内存状态
        initial_memory_usage_ = GetCurrentMemoryUsage();
    }

    void TearDown() override {
        // 检查内存泄漏
        size_t final_memory_usage = GetCurrentMemoryUsage();
        
        // 允许一定的内存增长容忍度（由于测试框架本身的开销）
        const size_t MEMORY_TOLERANCE = 1024 * 1024; // 1MB
        
        if (final_memory_usage > initial_memory_usage_ + MEMORY_TOLERANCE) {
            // 注意：这里只是警告，不会导致测试失败
            // 因为精确的内存泄漏检测需要专门的工具
            std::cout << "警告：可能存在内存泄漏。初始内存: " 
                      << initial_memory_usage_ << " 字节，最终内存: " 
                      << final_memory_usage << " 字节" << std::endl;
        }
    }

private:
    size_t initial_memory_usage_;
    
    // 获取当前内存使用量的简单实现
    // 注意：这是一个简化的实现，实际项目中应该使用更精确的方法
    size_t GetCurrentMemoryUsage() {
        // 在实际实现中，这里应该调用系统API获取内存使用量
        // 这里返回一个模拟值
        return 0;
    }
};

/**
 * 测试基本内存分配和释放
 */
TEST_F(MemoryManagementTest, TestBasicAllocationDeallocation) {
    const size_t ALLOCATION_SIZE = 1024 * 1024; // 1MB
    const int NUM_ALLOCATIONS = 100;
    
    std::vector<std::unique_ptr<char[]>> allocations;
    
    // 分配内存
    for (int i = 0; i < NUM_ALLOCATIONS; ++i) {
        auto ptr = std::make_unique<char[]>(ALLOCATION_SIZE);
        
        // 写入数据以确保内存真正分配
        memset(ptr.get(), i % 256, ALLOCATION_SIZE);
        
        allocations.push_back(std::move(ptr));
    }
    
    // 验证分配成功
    EXPECT_EQ(allocations.size(), NUM_ALLOCATIONS);
    
    // 验证数据完整性
    for (int i = 0; i < NUM_ALLOCATIONS; ++i) {
        EXPECT_EQ(static_cast<unsigned char>(allocations[i][0]), i % 256);
        EXPECT_EQ(static_cast<unsigned char>(allocations[i][ALLOCATION_SIZE - 1]), i % 256);
    }
    
    // 清理内存（通过unique_ptr自动管理）
    allocations.clear();
}

/**
 * 测试大块内存分配
 */
TEST_F(MemoryManagementTest, TestLargeMemoryAllocation) {
    const size_t LARGE_SIZE = 10 * 1024 * 1024; // 10MB (减少以避免内存不足)
    
    try {
        auto large_buffer = std::make_unique<char[]>(LARGE_SIZE);
        
        // 写入测试数据
        const char TEST_PATTERN[] = "WonderTrader";
        const size_t PATTERN_SIZE = sizeof(TEST_PATTERN) - 1;
        
        for (size_t i = 0; i < LARGE_SIZE; i += PATTERN_SIZE) {
            size_t copy_size = std::min(PATTERN_SIZE, LARGE_SIZE - i);
            memcpy(large_buffer.get() + i, TEST_PATTERN, copy_size);
        }
        
        // 验证数据完整性（抽样检查）
        std::vector<size_t> check_positions = {
            0, LARGE_SIZE / 4, LARGE_SIZE / 2, 
            3 * LARGE_SIZE / 4, LARGE_SIZE - PATTERN_SIZE
        };
        
        for (size_t pos : check_positions) {
            // 确保检查位置对齐到模式边界
            size_t aligned_pos = (pos / PATTERN_SIZE) * PATTERN_SIZE;
            if (aligned_pos + PATTERN_SIZE <= LARGE_SIZE) {
                EXPECT_EQ(memcmp(large_buffer.get() + aligned_pos, TEST_PATTERN, PATTERN_SIZE), 0)
                    << "内存模式验证失败，位置: " << aligned_pos;
            }
        }
        
    } catch (const std::bad_alloc& e) {
        // 如果系统内存不足，这是可以接受的
        GTEST_SKIP() << "系统内存不足，跳过大内存分配测试: " << e.what();
    }
}

/**
 * 测试内存对齐
 */
TEST_F(MemoryManagementTest, TestMemoryAlignment) {
    const size_t ALIGNMENT = 64; // 64字节对齐
    const size_t SIZE = 1024;
    const int NUM_ALLOCATIONS = 50;
    
    std::vector<std::unique_ptr<char, void(*)(void*)>> aligned_ptrs;
    
    for (int i = 0; i < NUM_ALLOCATIONS; ++i) {
        // 使用aligned_alloc分配对齐内存
        void* ptr = nullptr;
        
#ifdef _WIN32
        ptr = _aligned_malloc(SIZE, ALIGNMENT);
        auto deleter = [](void* p) { _aligned_free(p); };
#else
        if (posix_memalign(&ptr, ALIGNMENT, SIZE) != 0) {
            ptr = nullptr;
        }
        auto deleter = [](void* p) { free(p); };
#endif
        
        ASSERT_NE(ptr, nullptr) << "对齐内存分配失败";
        
        // 验证对齐
        EXPECT_EQ(reinterpret_cast<uintptr_t>(ptr) % ALIGNMENT, 0)
            << "内存未正确对齐到 " << ALIGNMENT << " 字节边界";
        
        // 写入测试数据
        memset(ptr, i % 256, SIZE);
        
        aligned_ptrs.emplace_back(static_cast<char*>(ptr), deleter);
    }
    
    // 验证数据完整性
    for (int i = 0; i < NUM_ALLOCATIONS; ++i) {
        EXPECT_EQ(static_cast<unsigned char>(aligned_ptrs[i].get()[0]), i % 256);
        EXPECT_EQ(static_cast<unsigned char>(aligned_ptrs[i].get()[SIZE - 1]), i % 256);
    }
}

/**
 * 测试并发内存分配
 */
TEST_F(MemoryManagementTest, TestConcurrentAllocation) {
    const int NUM_THREADS = 4;
    const int ALLOCATIONS_PER_THREAD = 1000;
    const size_t ALLOCATION_SIZE = 4096; // 4KB
    
    std::vector<std::thread> threads;
    std::atomic<int> successful_allocations(0);
    std::atomic<int> failed_allocations(0);
    
    for (int t = 0; t < NUM_THREADS; ++t) {
        threads.emplace_back([&, t]() {
            std::vector<std::unique_ptr<char[]>> local_allocations;
            
            for (int i = 0; i < ALLOCATIONS_PER_THREAD; ++i) {
                try {
                    auto ptr = std::make_unique<char[]>(ALLOCATION_SIZE);
                    
                    // 写入线程特定的数据
                    char pattern = static_cast<char>((t * 100 + i) % 256);
                    memset(ptr.get(), pattern, ALLOCATION_SIZE);
                    
                    local_allocations.push_back(std::move(ptr));
                    successful_allocations.fetch_add(1);
                    
                } catch (const std::bad_alloc&) {
                    failed_allocations.fetch_add(1);
                }
            }
            
            // 验证本线程分配的内存数据完整性
            for (size_t i = 0; i < local_allocations.size(); ++i) {
                char expected_pattern = static_cast<char>((t * 100 + i) % 256);
                EXPECT_EQ(static_cast<unsigned char>(local_allocations[i][0]), 
                         static_cast<unsigned char>(expected_pattern));
                EXPECT_EQ(static_cast<unsigned char>(local_allocations[i][ALLOCATION_SIZE - 1]), 
                         static_cast<unsigned char>(expected_pattern));
            }
        });
    }
    
    // 等待所有线程完成
    for (auto& thread : threads) {
        thread.join();
    }
    
    // 验证结果
    int total_attempts = NUM_THREADS * ALLOCATIONS_PER_THREAD;
    EXPECT_EQ(successful_allocations.load() + failed_allocations.load(), total_attempts);
    
    // 大部分分配应该成功
    EXPECT_GT(successful_allocations.load(), total_attempts * 0.9);
    
    std::cout << "并发内存分配测试结果: " 
              << successful_allocations.load() << " 成功, "
              << failed_allocations.load() << " 失败" << std::endl;
}

/**
 * 测试内存池模式
 */
TEST_F(MemoryManagementTest, TestMemoryPoolPattern) {
    // 简单的内存池实现用于测试
    class SimpleMemoryPool {
    public:
        SimpleMemoryPool(size_t block_size, size_t num_blocks) 
            : block_size_(block_size), num_blocks_(num_blocks) {
            
            // 分配大块内存
            pool_memory_ = std::make_unique<char[]>(block_size * num_blocks);
            
            // 初始化空闲块链表
            for (size_t i = 0; i < num_blocks; ++i) {
                free_blocks_.push_back(pool_memory_.get() + i * block_size);
            }
        }
        
        void* allocate() {
            if (free_blocks_.empty()) {
                return nullptr;
            }
            
            void* ptr = free_blocks_.back();
            free_blocks_.pop_back();
            allocated_blocks_++;
            return ptr;
        }
        
        void deallocate(void* ptr) {
            if (ptr >= pool_memory_.get() && 
                ptr < pool_memory_.get() + block_size_ * num_blocks_) {
                free_blocks_.push_back(ptr);
                allocated_blocks_--;
            }
        }
        
        size_t allocated_count() const { return allocated_blocks_; }
        size_t free_count() const { return free_blocks_.size(); }
        
    private:
        size_t block_size_;
        size_t num_blocks_;
        std::unique_ptr<char[]> pool_memory_;
        std::vector<void*> free_blocks_;
        std::atomic<size_t> allocated_blocks_{0};
    };
    
    const size_t BLOCK_SIZE = 256;
    const size_t NUM_BLOCKS = 1000;
    
    SimpleMemoryPool pool(BLOCK_SIZE, NUM_BLOCKS);
    
    // 测试分配
    std::vector<void*> allocated_ptrs;
    for (size_t i = 0; i < NUM_BLOCKS; ++i) {
        void* ptr = pool.allocate();
        ASSERT_NE(ptr, nullptr) << "内存池分配失败，索引: " << i;
        
        // 写入测试数据
        memset(ptr, i % 256, BLOCK_SIZE);
        allocated_ptrs.push_back(ptr);
    }
    
    EXPECT_EQ(pool.allocated_count(), NUM_BLOCKS);
    EXPECT_EQ(pool.free_count(), 0);
    
    // 测试池耗尽
    void* extra_ptr = pool.allocate();
    EXPECT_EQ(extra_ptr, nullptr);
    
    // 测试释放
    for (size_t i = 0; i < NUM_BLOCKS / 2; ++i) {
        pool.deallocate(allocated_ptrs[i]);
    }
    
    EXPECT_EQ(pool.allocated_count(), NUM_BLOCKS / 2);
    EXPECT_EQ(pool.free_count(), NUM_BLOCKS / 2);
    
    // 测试重新分配
    for (size_t i = 0; i < NUM_BLOCKS / 2; ++i) {
        void* ptr = pool.allocate();
        EXPECT_NE(ptr, nullptr);
        allocated_ptrs[i] = ptr;
    }
    
    EXPECT_EQ(pool.allocated_count(), NUM_BLOCKS);
    EXPECT_EQ(pool.free_count(), 0);
    
    // 清理所有分配的内存
    for (void* ptr : allocated_ptrs) {
        pool.deallocate(ptr);
    }
    
    EXPECT_EQ(pool.allocated_count(), 0);
    EXPECT_EQ(pool.free_count(), NUM_BLOCKS);
}

/**
 * 测试内存碎片化处理
 */
TEST_F(MemoryManagementTest, TestMemoryFragmentation) {
    const int NUM_ITERATIONS = 100;
    const size_t MIN_SIZE = 64;
    const size_t MAX_SIZE = 4096;
    
    std::vector<std::unique_ptr<char[]>> allocations;
    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
    std::uniform_int_distribution<size_t> size_dist(MIN_SIZE, MAX_SIZE);
    std::uniform_int_distribution<int> action_dist(0, 2); // 0: allocate, 1: deallocate, 2: reallocate
    
    for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {
        int action = action_dist(rng);
        
        if (action == 0 || allocations.empty()) {
            // 分配新内存
            size_t size = size_dist(rng);
            try {
                auto ptr = std::make_unique<char[]>(size);
                
                // 写入测试数据
                char pattern = static_cast<char>(iter % 256);
                memset(ptr.get(), pattern, size);
                
                allocations.push_back(std::move(ptr));
                
            } catch (const std::bad_alloc&) {
                // 内存不足是可以接受的
            }
            
        } else if (action == 1 && !allocations.empty()) {
            // 释放随机内存块
            std::uniform_int_distribution<size_t> index_dist(0, allocations.size() - 1);
            size_t index = index_dist(rng);
            
            allocations.erase(allocations.begin() + index);
            
        } else if (action == 2 && !allocations.empty()) {
            // 重新分配（模拟realloc）
            std::uniform_int_distribution<size_t> index_dist(0, allocations.size() - 1);
            size_t index = index_dist(rng);
            size_t new_size = size_dist(rng);
            
            try {
                auto new_ptr = std::make_unique<char[]>(new_size);
                
                // 复制旧数据（如果有的话）
                // 这里简化处理，只写入新的测试数据
                char pattern = static_cast<char>(iter % 256);
                memset(new_ptr.get(), pattern, new_size);
                
                allocations[index] = std::move(new_ptr);
                
            } catch (const std::bad_alloc&) {
                // 重新分配失败，保持原有内存
            }
        }
    }
    
    // 验证剩余分配的内存仍然有效
    for (const auto& ptr : allocations) {
        EXPECT_NE(ptr.get(), nullptr);
        // 简单的读写测试
        ptr[0] = 'T';
        EXPECT_EQ(ptr[0], 'T');
    }
    
    std::cout << "内存碎片化测试完成，最终分配块数: " << allocations.size() << std::endl;
}

/**
 * 测试RAII（资源获取即初始化）模式
 */
TEST_F(MemoryManagementTest, TestRAIIPattern) {
    // 简化的RAII测试，避免静态成员问题
    {
        std::vector<std::unique_ptr<char[]>> resources;
        
        // 创建资源
        for (int i = 0; i < 10; ++i) {
            auto resource = std::make_unique<char[]>(1024 * (i + 1));
            memset(resource.get(), 0xAA, 1024 * (i + 1));
            resources.push_back(std::move(resource));
        }
        
        EXPECT_EQ(resources.size(), 10);
        
        // 验证资源
        for (size_t i = 0; i < resources.size(); ++i) {
            EXPECT_NE(resources[i].get(), nullptr);
            EXPECT_EQ(static_cast<unsigned char>(resources[i][0]), 0xAA);
        }
        
    } // 作用域结束，所有资源应该被自动释放
    
    // 测试移动语义
    {
        auto resource1 = std::make_unique<char[]>(1024);
        memset(resource1.get(), 0xBB, 1024);
        
        auto resource2 = std::move(resource1);
        
        EXPECT_EQ(resource1.get(), nullptr);
        EXPECT_NE(resource2.get(), nullptr);
        EXPECT_EQ(static_cast<unsigned char>(resource2[0]), 0xBB);
    }
}
